<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN">
<HTML>
<HEAD>
<LINK REL=STYLESHEET TYPE="text/css" HREF="../../stylesheet.css" TITLE="Style">
<META NAME="GENERATOR" CONTENT="Java2HTML Version 1.5">
<TITLE>czestmyr.jjsched.Config (Java2HTML)</TITLE>
</HEAD>
<BODY><TABLE id="Header" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td colspan="2" width="33%">&nbsp;</td>
<td align="center" colspan="2" width="33%">
<font size="4">Config.java</font>
</td>
<td align="right" colspan="2" width="33%">&nbsp;</td>
</tr>
</TABLE>
<pre ID="Classes">
<A NAME="1"></A><FONT ID="MultiLineComment">/*  This file is a part of JJSched source code
<A NAME="2"></A>    JJSched - Java Jabber Scheduler - a simple Jabber scheduling application
<A NAME="3"></A>    Copyright (C) 2008 Cestmir "CZestmyr" Houska
<A NAME="4"></A>
<A NAME="5"></A>    This program is free software: you can redistribute it and/or modify
<A NAME="6"></A>    it under the terms of the GNU General Public License as published by
<A NAME="7"></A>    the Free Software Foundation, either version 3 of the License, or
<A NAME="8"></A>    (at your option) any later version.
<A NAME="9"></A>
<A NAME="10"></A>    This program is distributed in the hope that it will be useful,
<A NAME="11"></A>    but WITHOUT ANY WARRANTY; without even the implied warranty of
<A NAME="12"></A>    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
<A NAME="13"></A>    GNU General Public License for more details.
<A NAME="14"></A>
<A NAME="15"></A>    You should have received a copy of the GNU General Public License
<A NAME="16"></A>    along with this program.  If not, see &lt;http://www.gnu.org/licenses/&gt; */</FONT>
<A NAME="17"></A>
<A NAME="18"></A><FONT ID="Package">package</FONT> czestmyr.jjsched;
<A NAME="19"></A>
<A NAME="20"></A><FONT ID="Import">import</FONT> java.lang.*;
<A NAME="21"></A><FONT ID="Import">import</FONT> java.util.*;
<A NAME="22"></A><FONT ID="Import">import</FONT> java.io.*;
<A NAME="23"></A>
<A NAME="24"></A><FONT ID="FormalComment">/**
<A NAME="25"></A> * Processes the configuration options specified in the configuration file.
<A NAME="26"></A> * Also stores these options within itself and stores global macros in the
<A NAME="27"></A> * provided instance of Macros class
<A NAME="28"></A> */</FONT>
<A NAME="29"></A><FONT ID="Public">public</FONT> <FONT ID="Class">class</FONT> Config{
<A NAME="30"></A>    <FONT ID="FormalComment">/**
<A NAME="31"></A>     * Constructor. This class needs the macro class reference to be able to store the
<A NAME="32"></A>     * macro definitions in it.
<A NAME="33"></A>     *
<A NAME="34"></A>     * @param   macros  Instance of the class Macros that will be modified 
<A NAME="35"></A>     */</FONT>
<A NAME="36"></A>    Config(<A HREF="../../czestmyr/jjsched/Macros.java.html">Macros</A> macros){
<A NAME="37"></A>        theMacros = macros;
<A NAME="38"></A>    }
<A NAME="39"></A>
<A NAME="40"></A>    <FONT ID="FormalComment">/**
<A NAME="41"></A>     * Parses the given configuration file. Read the example configuration file in
<A NAME="42"></A>     * the JJSched directory or in user documentation to learn more about configuration
<A NAME="43"></A>     * file of JJSched
<A NAME="44"></A>     *
<A NAME="45"></A>     * @param   configFilename  The path to the configuration file with configuration for
<A NAME="46"></A>     *                          JJSched
<A NAME="47"></A>     * @throws  Exception       If the file cannot be accesses or if it does not exist.
<A NAME="48"></A>     *                          An exception is also thrown in case of incorrect format
<A NAME="49"></A>     *                          of the configuration file
<A NAME="50"></A>     */</FONT>
<A NAME="51"></A>    <FONT ID="Public">public</FONT> <FONT ID="Void">void</FONT> parse(String configFilename) <FONT ID="Throws">throws</FONT> Exception{
<A NAME="52"></A>        BufferedReader bRead = <FONT ID="New">new</FONT> BufferedReader(<FONT ID="New">new</FONT> FileReader(configFilename));
<A NAME="53"></A>
<A NAME="54"></A>        String line;
<A NAME="55"></A>        <FONT ID="While">while</FONT> ((line = bRead.readLine()) != <FONT ID="Null">null</FONT>){
<A NAME="56"></A>            LinkedList&lt;String&gt; lineTokens = StringParser.parseLine(line);
<A NAME="57"></A>
<A NAME="58"></A>            <FONT ID="If">if</FONT> (lineTokens.isEmpty()) <FONT ID="Continue">continue</FONT>;
<A NAME="59"></A>
<A NAME="60"></A>            States s = States.INITIAL;
<A NAME="61"></A>            String keyword = <FONT ID="Null">null</FONT>;
<A NAME="62"></A>            Vector&lt;String&gt; body;
<A NAME="63"></A>
<A NAME="64"></A>            Iterator it = lineTokens.iterator();
<A NAME="65"></A>            <FONT ID="Int">int</FONT> i = <FONT ID="IntegerLiteral">0</FONT>;
<A NAME="66"></A>            <FONT ID="While">while</FONT> (it.hasNext()){
<A NAME="67"></A>                String currentToken = (String)it.next();
<A NAME="68"></A>                <FONT ID="Switch">switch</FONT>(s){
<A NAME="69"></A>                    <FONT ID="Case">case</FONT> INITIAL:
<A NAME="70"></A>                        <FONT ID="If">if</FONT> (currentToken.compareTo(<FONT ID="StringLiteral">"macro"</FONT>) == <FONT ID="IntegerLiteral">0</FONT>)
<A NAME="71"></A>                            s = States.MACRO;
<A NAME="72"></A>                        <FONT ID="Else">else</FONT> {
<A NAME="73"></A>                            <FONT ID="If">if</FONT> (currentToken.compareTo(<FONT ID="StringLiteral">"="</FONT>) == <FONT ID="IntegerLiteral">0</FONT>)
<A NAME="74"></A>                                <FONT ID="Throw">throw</FONT> <FONT ID="New">new</FONT> Exception(<FONT ID="StringLiteral">"Keyword or option name expected as first token: "</FONT>+line);
<A NAME="75"></A>                            keyword = currentToken;
<A NAME="76"></A>                            s = States.OPERATOR;
<A NAME="77"></A>                        }
<A NAME="78"></A>                    <FONT ID="Break">break</FONT>;
<A NAME="79"></A>                    <FONT ID="Case">case</FONT> MACRO:
<A NAME="80"></A>                        <FONT ID="If">if</FONT> (currentToken.compareTo(<FONT ID="StringLiteral">"="</FONT>) == <FONT ID="IntegerLiteral">0</FONT>)
<A NAME="81"></A>                            <FONT ID="Throw">throw</FONT> <FONT ID="New">new</FONT> Exception(<FONT ID="StringLiteral">"Macro keyword expected: "</FONT>+line);
<A NAME="82"></A>                        <FONT ID="Else">else</FONT> {
<A NAME="83"></A>                            keyword = currentToken;
<A NAME="84"></A>                            s = States.OPERATORMACRO;
<A NAME="85"></A>                        }
<A NAME="86"></A>                    <FONT ID="Break">break</FONT>;
<A NAME="87"></A>                    <FONT ID="Case">case</FONT> OPERATOR:
<A NAME="88"></A>                        <FONT ID="If">if</FONT> (currentToken.compareTo(<FONT ID="StringLiteral">"="</FONT>) != <FONT ID="IntegerLiteral">0</FONT>)
<A NAME="89"></A>                            <FONT ID="Throw">throw</FONT> <FONT ID="New">new</FONT> Exception(<FONT ID="StringLiteral">"Operator '=' expected after option name: "</FONT>+line);
<A NAME="90"></A>                        <FONT ID="Else">else</FONT> s = States.VALUE;
<A NAME="91"></A>                    <FONT ID="Break">break</FONT>;
<A NAME="92"></A>                    <FONT ID="Case">case</FONT> OPERATORMACRO:
<A NAME="93"></A>                        <FONT ID="If">if</FONT> (currentToken.compareTo(<FONT ID="StringLiteral">"="</FONT>) != <FONT ID="IntegerLiteral">0</FONT>)
<A NAME="94"></A>                            <FONT ID="Throw">throw</FONT> <FONT ID="New">new</FONT> Exception(<FONT ID="StringLiteral">"Operator '=' expected after macro keyword: "</FONT>+line);
<A NAME="95"></A>                        <FONT ID="Else">else</FONT> s = States.BODY;
<A NAME="96"></A>                    <FONT ID="Break">break</FONT>;
<A NAME="97"></A>                    <FONT ID="Case">case</FONT> VALUE:
<A NAME="98"></A>                        <FONT ID="If">if</FONT> (currentToken.compareTo(<FONT ID="StringLiteral">"int"</FONT>) == <FONT ID="IntegerLiteral">0</FONT>)
<A NAME="99"></A>                            s = States.INTVALUE;
<A NAME="100"></A>                        <FONT ID="Else">else</FONT> {
<A NAME="101"></A>                            options.put(keyword, currentToken);
<A NAME="102"></A>                            s = States.END;
<A NAME="103"></A>                        }
<A NAME="104"></A>                    <FONT ID="Break">break</FONT>;
<A NAME="105"></A>                    <FONT ID="Case">case</FONT> BODY:
<A NAME="106"></A>                        theMacros.newMacro(keyword, lineTokens.subList(i, lineTokens.size()).iterator());
<A NAME="107"></A>                        <FONT ID="While">while</FONT> (it.hasNext()) it.next();
<A NAME="108"></A>                        s = States.END;
<A NAME="109"></A>                    <FONT ID="Break">break</FONT>;
<A NAME="110"></A>                    <FONT ID="Case">case</FONT> INTVALUE:
<A NAME="111"></A>                        options.put(keyword, <FONT ID="New">new</FONT> Integer(currentToken));
<A NAME="112"></A>                        s = States.END;
<A NAME="113"></A>                    <FONT ID="Break">break</FONT>;
<A NAME="114"></A>                    <FONT ID="Case">case</FONT> END:
<A NAME="115"></A>                        <FONT ID="Throw">throw</FONT> <FONT ID="New">new</FONT> Exception(<FONT ID="StringLiteral">"Further tokens after legal construct: "</FONT>+line);
<A NAME="116"></A>                }
<A NAME="117"></A>                ++i;
<A NAME="118"></A>            }
<A NAME="119"></A>
<A NAME="120"></A>            <FONT ID="If">if</FONT> (s != States.END &amp;&amp; s != States.INITIAL)
<A NAME="121"></A>                <FONT ID="Throw">throw</FONT> <FONT ID="New">new</FONT> Exception(<FONT ID="StringLiteral">"Incomplete option definition: "</FONT>+line);
<A NAME="122"></A>        }
<A NAME="123"></A>    }
<A NAME="124"></A>
<A NAME="125"></A>    <FONT ID="FormalComment">/**
<A NAME="126"></A>     * Returns the value of the given configuration option as String.
<A NAME="127"></A>     * Configuration options can be either strings or integers, so you cannot use this
<A NAME="128"></A>     * method for the same keyword along with the getInt(String keyword) method.
<A NAME="129"></A>     *
<A NAME="130"></A>     * @param   keyword The keyword of the sought option
<A NAME="131"></A>     * @return          The String value of the given option
<A NAME="132"></A>     */</FONT>
<A NAME="133"></A>    <FONT ID="Public">public</FONT> String getString(String keyword){
<A NAME="134"></A>        <FONT ID="If">if</FONT> (options.get(keyword).getClass().getName() == <FONT ID="StringLiteral">"java.lang.Integer"</FONT>){
<A NAME="135"></A>            <FONT ID="Return">return</FONT> <FONT ID="Null">null</FONT>;
<A NAME="136"></A>        }
<A NAME="137"></A>        <FONT ID="Return">return</FONT> (String)options.get(keyword);
<A NAME="138"></A>    }
<A NAME="139"></A>
<A NAME="140"></A>    <FONT ID="FormalComment">/**
<A NAME="141"></A>     * Returns the value of the given configuration option as Integer.
<A NAME="142"></A>     * Configuration options can be either strings or integers, so you cannot use this
<A NAME="143"></A>     * method for the same keyword along with the getString(String keyword) method.
<A NAME="144"></A>     *
<A NAME="145"></A>     * @param   keyword The keyword of the sought option
<A NAME="146"></A>     * @return          The value of the given option as an Integer
<A NAME="147"></A>     */</FONT>
<A NAME="148"></A>    <FONT ID="Public">public</FONT> Integer getInt(String keyword){
<A NAME="149"></A>        <FONT ID="If">if</FONT> (options.get(keyword).getClass().getName() == <FONT ID="StringLiteral">"java.lang.String"</FONT>){
<A NAME="150"></A>            <FONT ID="Return">return</FONT> <FONT ID="Null">null</FONT>;
<A NAME="151"></A>        }
<A NAME="152"></A>        <FONT ID="Return">return</FONT> (Integer)options.get(keyword);
<A NAME="153"></A>    }
<A NAME="154"></A>
<A NAME="155"></A>    <FONT ID="FormalComment">/** Reference to the instance of the class that holds macro definitions */</FONT>
<A NAME="156"></A>    <FONT ID="Private">private</FONT> <A HREF="../../czestmyr/jjsched/Macros.java.html">Macros</A> theMacros;
<A NAME="157"></A>
<A NAME="158"></A>    <FONT ID="FormalComment">/** Hash map for storing the option values */</FONT>
<A NAME="159"></A>    <FONT ID="Private">private</FONT> HashMap&lt;String, Object&gt; options = <FONT ID="New">new</FONT> HashMap&lt;String, Object&gt;();
<A NAME="160"></A>}
<A NAME="161"></A>
<A NAME="162"></A><FONT ID="FormalComment">/**
<A NAME="163"></A> * Enumeration of states of the config parser automaton
<A NAME="164"></A> */</FONT>
<A NAME="165"></A>enum States{
<A NAME="166"></A>    INITIAL, MACRO, OPERATOR, OPERATORMACRO, VALUE, BODY, INTVALUE, END
<A NAME="167"></A>}</pre>
</BODY>
</HTML>